{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 导入必要的工具包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 读取特征工程后的CSV数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>instant</th>\n",
       "      <th>season_1</th>\n",
       "      <th>season_2</th>\n",
       "      <th>season_3</th>\n",
       "      <th>season_4</th>\n",
       "      <th>mnth_1</th>\n",
       "      <th>mnth_2</th>\n",
       "      <th>mnth_3</th>\n",
       "      <th>mnth_4</th>\n",
       "      <th>mnth_5</th>\n",
       "      <th>...</th>\n",
       "      <th>weekday_5</th>\n",
       "      <th>weekday_6</th>\n",
       "      <th>temp</th>\n",
       "      <th>atemp</th>\n",
       "      <th>hum</th>\n",
       "      <th>windspeed</th>\n",
       "      <th>holiday</th>\n",
       "      <th>workingday</th>\n",
       "      <th>yr</th>\n",
       "      <th>cnt</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0.355170</td>\n",
       "      <td>0.373517</td>\n",
       "      <td>0.828620</td>\n",
       "      <td>0.284606</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>985</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.379232</td>\n",
       "      <td>0.360541</td>\n",
       "      <td>0.715771</td>\n",
       "      <td>0.466215</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>801</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.171000</td>\n",
       "      <td>0.144830</td>\n",
       "      <td>0.449638</td>\n",
       "      <td>0.465740</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1349</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.175530</td>\n",
       "      <td>0.174649</td>\n",
       "      <td>0.607131</td>\n",
       "      <td>0.284297</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1562</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.209120</td>\n",
       "      <td>0.197158</td>\n",
       "      <td>0.449313</td>\n",
       "      <td>0.339143</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1600</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 35 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   instant  season_1  season_2  season_3  season_4  mnth_1  mnth_2  mnth_3  \\\n",
       "0        1         1         0         0         0       1       0       0   \n",
       "1        2         1         0         0         0       1       0       0   \n",
       "2        3         1         0         0         0       1       0       0   \n",
       "3        4         1         0         0         0       1       0       0   \n",
       "4        5         1         0         0         0       1       0       0   \n",
       "\n",
       "   mnth_4  mnth_5  ...   weekday_5  weekday_6      temp     atemp       hum  \\\n",
       "0       0       0  ...           0          1  0.355170  0.373517  0.828620   \n",
       "1       0       0  ...           0          0  0.379232  0.360541  0.715771   \n",
       "2       0       0  ...           0          0  0.171000  0.144830  0.449638   \n",
       "3       0       0  ...           0          0  0.175530  0.174649  0.607131   \n",
       "4       0       0  ...           0          0  0.209120  0.197158  0.449313   \n",
       "\n",
       "   windspeed  holiday  workingday  yr   cnt  \n",
       "0   0.284606        0           0   0   985  \n",
       "1   0.466215        0           0   0   801  \n",
       "2   0.465740        0           1   0  1349  \n",
       "3   0.284297        0           1   0  1562  \n",
       "4   0.339143        0           1   0  1600  \n",
       "\n",
       "[5 rows x 35 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data =  pd.read_csv(\"FE_day.csv\")\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(731, 35)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据准备"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#从原始数据中分离输入特征x和输入y\n",
    "y = data['cnt']\n",
    "x = data.drop('cnt',axis = 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 对全体数据，随机选择其中80%做训练数据，剩下20%为测试数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(584, 34) (147, 34)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=666, test_size=0.2)\n",
    "\n",
    "print(x_train.shape, x_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模型训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 最小二重线性回归模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "\n",
    "#1.使用默认配置初始化学习器实例\n",
    "lr = LinearRegression()\n",
    "\n",
    "#2.用训练数据训练模型参数\n",
    "lr.fit(x_train, y_train)\n",
    "\n",
    "#3.用训练好的模型对测试集进行预测\n",
    "y_test_pred_lr = lr.predict(x_test)\n",
    "y_train_pred_lr = lr.predict(x_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coef</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>33</th>\n",
       "      <td>yr</td>\n",
       "      <td>4549.136402</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>temp</td>\n",
       "      <td>2707.682487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>mnth_9</td>\n",
       "      <td>1160.174124</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>atemp</td>\n",
       "      <td>934.351609</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>mnth_10</td>\n",
       "      <td>931.733359</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>weathersit_1</td>\n",
       "      <td>799.605197</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>mnth_12</td>\n",
       "      <td>772.941496</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>season_4</td>\n",
       "      <td>738.438403</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>mnth_11</td>\n",
       "      <td>548.637073</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>weathersit_2</td>\n",
       "      <td>305.260698</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>mnth_8</td>\n",
       "      <td>297.994160</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>workingday</td>\n",
       "      <td>218.604212</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>weekday_6</td>\n",
       "      <td>199.112550</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>weekday_5</td>\n",
       "      <td>124.568266</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>season_2</td>\n",
       "      <td>110.400044</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>season_3</td>\n",
       "      <td>101.446644</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>mnth_6</td>\n",
       "      <td>68.420351</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>mnth_5</td>\n",
       "      <td>37.369007</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>weekday_4</td>\n",
       "      <td>17.272060</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>weekday_3</td>\n",
       "      <td>-6.322377</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>instant</td>\n",
       "      <td>-6.971132</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>weekday_2</td>\n",
       "      <td>-57.090077</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>weekday_0</td>\n",
       "      <td>-124.586626</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>weekday_1</td>\n",
       "      <td>-152.953796</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31</th>\n",
       "      <td>holiday</td>\n",
       "      <td>-293.130136</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>mnth_7</td>\n",
       "      <td>-376.266654</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>mnth_4</td>\n",
       "      <td>-454.993618</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>mnth_3</td>\n",
       "      <td>-606.211203</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>season_1</td>\n",
       "      <td>-950.285090</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>mnth_2</td>\n",
       "      <td>-1026.132943</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>weathersit_3</td>\n",
       "      <td>-1104.865895</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>windspeed</td>\n",
       "      <td>-1245.444147</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>mnth_1</td>\n",
       "      <td>-1353.665152</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>hum</td>\n",
       "      <td>-1583.508532</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         columns         coef\n",
       "33            yr  4549.136402\n",
       "27          temp  2707.682487\n",
       "13        mnth_9  1160.174124\n",
       "28         atemp   934.351609\n",
       "14       mnth_10   931.733359\n",
       "17  weathersit_1   799.605197\n",
       "16       mnth_12   772.941496\n",
       "4       season_4   738.438403\n",
       "15       mnth_11   548.637073\n",
       "18  weathersit_2   305.260698\n",
       "12        mnth_8   297.994160\n",
       "32    workingday   218.604212\n",
       "26     weekday_6   199.112550\n",
       "25     weekday_5   124.568266\n",
       "2       season_2   110.400044\n",
       "3       season_3   101.446644\n",
       "10        mnth_6    68.420351\n",
       "9         mnth_5    37.369007\n",
       "24     weekday_4    17.272060\n",
       "23     weekday_3    -6.322377\n",
       "0        instant    -6.971132\n",
       "22     weekday_2   -57.090077\n",
       "20     weekday_0  -124.586626\n",
       "21     weekday_1  -152.953796\n",
       "31       holiday  -293.130136\n",
       "11        mnth_7  -376.266654\n",
       "8         mnth_4  -454.993618\n",
       "7         mnth_3  -606.211203\n",
       "1       season_1  -950.285090\n",
       "6         mnth_2 -1026.132943\n",
       "19  weathersit_3 -1104.865895\n",
       "30     windspeed -1245.444147\n",
       "5         mnth_1 -1353.665152\n",
       "29           hum -1583.508532"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#看看各特征的权重系数,系数的绝对值大小可视为该特征的重要性\n",
    "feat_names = x.columns\n",
    "fs = pd.DataFrame({\"columns\":list(feat_names), \"coef\":list((lr.coef_.T))})\n",
    "fs.sort_values(by=['coef'], ascending = False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 最小二重线性回归模型评价 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test_err: 767.5194219703998\n",
      "train_err: 753.9986331255436\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.metrics import r2_score\n",
    "\n",
    "# 分别计算训练集和测试集上的RMSE(RMSE=MSE**0.5)\n",
    "train_err = mean_squared_error(y_train, y_train_pred_lr)**0.5\n",
    "test_err = mean_squared_error(y_test, y_test_pred_lr)**0.5\n",
    "\n",
    "print(\"test_err:\",test_err)\n",
    "print(\"train_err:\",train_err)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test_err: 0.8393985346561049\n",
      "train_err: 0.8488577427293332\n"
     ]
    }
   ],
   "source": [
    "# 分别计算训练集和测试集上的r2_score\n",
    "train_err = r2_score(y_train, y_train_pred_lr)\n",
    "test_err = r2_score(y_test, y_test_pred_lr)\n",
    "\n",
    "print(\"test_err:\",test_err)\n",
    "print(\"train_err:\",train_err)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 领回归模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "alpha is: 1.0\n"
     ]
    }
   ],
   "source": [
    "from sklearn.linear_model import RidgeCV\n",
    "\n",
    "#1.设置正则参数范围\n",
    "alphas = [0.01, 0.1, 1,10, 100]\n",
    "\n",
    "#2.生成一个RidgeCV实例\n",
    "ridge = RidgeCV(alphas = alphas, store_cv_values = True)\n",
    "\n",
    "#3.模型训练\n",
    "ridge.fit(x_train, y_train)\n",
    "\n",
    "#4.预测\n",
    "y_test_pred_ridge = ridge.predict(x_test)\n",
    "y_train_pred_ridge = ridge.predict(x_train)\n",
    "\n",
    "#可视化最佳参数\n",
    "mse_mean = np.mean(ridge.cv_values_, axis = 0)\n",
    "plt.plot(np.log10(alphas), mse_mean.reshape(len(alphas),1))\n",
    "\n",
    "plt.xlabel(\"log(alpha)\")\n",
    "plt.ylabel(\"mse\")\n",
    "plt.show()\n",
    "\n",
    "print(\"alpha is:\", ridge.alpha_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coef_lr</th>\n",
       "      <th>coef_ridge</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>33</th>\n",
       "      <td>yr</td>\n",
       "      <td>4549.136402</td>\n",
       "      <td>1544.674723</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>temp</td>\n",
       "      <td>2707.682487</td>\n",
       "      <td>1765.881620</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>mnth_9</td>\n",
       "      <td>1160.174124</td>\n",
       "      <td>574.895356</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>atemp</td>\n",
       "      <td>934.351609</td>\n",
       "      <td>1527.867002</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>mnth_10</td>\n",
       "      <td>931.733359</td>\n",
       "      <td>58.155429</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>weathersit_1</td>\n",
       "      <td>799.605197</td>\n",
       "      <td>805.001535</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>mnth_12</td>\n",
       "      <td>772.941496</td>\n",
       "      <td>-675.761308</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>season_4</td>\n",
       "      <td>738.438403</td>\n",
       "      <td>709.837923</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>mnth_11</td>\n",
       "      <td>548.637073</td>\n",
       "      <td>-610.471057</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>weathersit_2</td>\n",
       "      <td>305.260698</td>\n",
       "      <td>283.485003</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>mnth_8</td>\n",
       "      <td>297.994160</td>\n",
       "      <td>36.319840</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>workingday</td>\n",
       "      <td>218.604212</td>\n",
       "      <td>209.455573</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>weekday_6</td>\n",
       "      <td>199.112550</td>\n",
       "      <td>182.578689</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>weekday_5</td>\n",
       "      <td>124.568266</td>\n",
       "      <td>124.306939</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>season_2</td>\n",
       "      <td>110.400044</td>\n",
       "      <td>124.005754</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>season_3</td>\n",
       "      <td>101.446644</td>\n",
       "      <td>106.470624</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>mnth_6</td>\n",
       "      <td>68.420351</td>\n",
       "      <td>282.879825</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>mnth_5</td>\n",
       "      <td>37.369007</td>\n",
       "      <td>430.570732</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>weekday_4</td>\n",
       "      <td>17.272060</td>\n",
       "      <td>29.079490</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>weekday_3</td>\n",
       "      <td>-6.322377</td>\n",
       "      <td>3.072918</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>instant</td>\n",
       "      <td>-6.971132</td>\n",
       "      <td>1.272780</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>weekday_2</td>\n",
       "      <td>-57.090077</td>\n",
       "      <td>-50.509294</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>weekday_0</td>\n",
       "      <td>-124.586626</td>\n",
       "      <td>-132.906082</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>weekday_1</td>\n",
       "      <td>-152.953796</td>\n",
       "      <td>-155.622660</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31</th>\n",
       "      <td>holiday</td>\n",
       "      <td>-293.130136</td>\n",
       "      <td>-259.128180</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>mnth_7</td>\n",
       "      <td>-376.266654</td>\n",
       "      <td>-368.511624</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>mnth_4</td>\n",
       "      <td>-454.993618</td>\n",
       "      <td>145.732564</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>mnth_3</td>\n",
       "      <td>-606.211203</td>\n",
       "      <td>216.712947</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>season_1</td>\n",
       "      <td>-950.285090</td>\n",
       "      <td>-940.314301</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>mnth_2</td>\n",
       "      <td>-1026.132943</td>\n",
       "      <td>7.414244</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>weathersit_3</td>\n",
       "      <td>-1104.865895</td>\n",
       "      <td>-1088.486537</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>windspeed</td>\n",
       "      <td>-1245.444147</td>\n",
       "      <td>-1096.277524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>mnth_1</td>\n",
       "      <td>-1353.665152</td>\n",
       "      <td>-97.936948</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>hum</td>\n",
       "      <td>-1583.508532</td>\n",
       "      <td>-1353.554908</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         columns      coef_lr   coef_ridge\n",
       "33            yr  4549.136402  1544.674723\n",
       "27          temp  2707.682487  1765.881620\n",
       "13        mnth_9  1160.174124   574.895356\n",
       "28         atemp   934.351609  1527.867002\n",
       "14       mnth_10   931.733359    58.155429\n",
       "17  weathersit_1   799.605197   805.001535\n",
       "16       mnth_12   772.941496  -675.761308\n",
       "4       season_4   738.438403   709.837923\n",
       "15       mnth_11   548.637073  -610.471057\n",
       "18  weathersit_2   305.260698   283.485003\n",
       "12        mnth_8   297.994160    36.319840\n",
       "32    workingday   218.604212   209.455573\n",
       "26     weekday_6   199.112550   182.578689\n",
       "25     weekday_5   124.568266   124.306939\n",
       "2       season_2   110.400044   124.005754\n",
       "3       season_3   101.446644   106.470624\n",
       "10        mnth_6    68.420351   282.879825\n",
       "9         mnth_5    37.369007   430.570732\n",
       "24     weekday_4    17.272060    29.079490\n",
       "23     weekday_3    -6.322377     3.072918\n",
       "0        instant    -6.971132     1.272780\n",
       "22     weekday_2   -57.090077   -50.509294\n",
       "20     weekday_0  -124.586626  -132.906082\n",
       "21     weekday_1  -152.953796  -155.622660\n",
       "31       holiday  -293.130136  -259.128180\n",
       "11        mnth_7  -376.266654  -368.511624\n",
       "8         mnth_4  -454.993618   145.732564\n",
       "7         mnth_3  -606.211203   216.712947\n",
       "1       season_1  -950.285090  -940.314301\n",
       "6         mnth_2 -1026.132943     7.414244\n",
       "19  weathersit_3 -1104.865895 -1088.486537\n",
       "30     windspeed -1245.444147 -1096.277524\n",
       "5         mnth_1 -1353.665152   -97.936948\n",
       "29           hum -1583.508532 -1353.554908"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#确认各特征的权重系数,系数的绝对值大小可视为该特征的重要性\n",
    "fs = pd.DataFrame({\"columns\": list(feat_names), \"coef_lr\":list((lr.coef_.T)), \"coef_ridge\":list((ridge.coef_.T))})\n",
    "fs.sort_values(by = [\"coef_lr\"], ascending = False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 领回归模型评价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The RMSE of RidgeCV on test is 770.2419741671653\n",
      "The RMSE of RidgeCV on train is 758.8247755198331\n"
     ]
    }
   ],
   "source": [
    "# 评估，使用RMSE评价模型在测试集和训练集上的性能\n",
    "print('The RMSE of RidgeCV on test is', mean_squared_error(y_test, y_test_pred_ridge)**0.5)\n",
    "print('The RMSE of RidgeCV on train is', mean_squared_error(y_train, y_train_pred_ridge)**0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The r2_score of RidgeCV on test is 0.8382571397647272\n",
      "The r2_score of RidgeCV on train is 0.8469167086775348\n"
     ]
    }
   ],
   "source": [
    "# 评估，使用r2_score评价模型在测试集和训练集上的性能\n",
    "print('The r2_score of RidgeCV on test is', r2_score(y_test, y_test_pred_ridge))\n",
    "print('The r2_score of RidgeCV on train is', r2_score(y_train, y_train_pred_ridge))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 领回归模型超参数调优 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "       estimator=Ridge(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=None,\n",
       "   normalize=False, random_state=None, solver='auto', tol=0.001),\n",
       "       fit_params=None, iid='warn', n_jobs=None,\n",
       "       param_grid={'alpha': [0.01, 0.1, 1, 10, 100]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring=None, verbose=0)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import Ridge\n",
    "param_grid = {'alpha':[0.01, 0.1, 1, 10, 100]}\n",
    "grid_search = GridSearchCV(Ridge(), param_grid, cv=5)\n",
    "grid_search.fit(x_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'alpha': 1}\n"
     ]
    }
   ],
   "source": [
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lasso模型 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "alpha is: 1.0\n"
     ]
    }
   ],
   "source": [
    "from sklearn.linear_model import LassoCV\n",
    "\n",
    "#1.设置超参数搜索范围\n",
    "alphas = [0.01, 0.1, 1, 10, 100]\n",
    "\n",
    "#2.生成学习器实例\n",
    "lasso = LassoCV(alphas=alphas)\n",
    "\n",
    "#3.训练（内含CV）\n",
    "lasso.fit(x_train, y_train)\n",
    "\n",
    "#4.预测\n",
    "y_test_pred_lasso = lasso.predict(x_test)\n",
    "y_train_pred_lasso = lasso.predict(x_train)\n",
    "\n",
    "# 可视化最佳参数\n",
    "mses = np.mean(lasso.mse_path_, axis = 1)\n",
    "plt.plot(np.log10(lasso.alphas_), mses)\n",
    "plt.xlabel('log(alpha)')\n",
    "plt.ylabel('mse')\n",
    "plt.show()    \n",
    "            \n",
    "print ('alpha is:', lasso.alpha_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coef_lr</th>\n",
       "      <th>coef_ridge</th>\n",
       "      <th>coef_lasso</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>33</th>\n",
       "      <td>yr</td>\n",
       "      <td>4549.136402</td>\n",
       "      <td>1544.674723</td>\n",
       "      <td>2358.983279</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>temp</td>\n",
       "      <td>2707.682487</td>\n",
       "      <td>1765.881620</td>\n",
       "      <td>2679.387928</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>mnth_9</td>\n",
       "      <td>1160.174124</td>\n",
       "      <td>574.895356</td>\n",
       "      <td>678.656820</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>atemp</td>\n",
       "      <td>934.351609</td>\n",
       "      <td>1527.867002</td>\n",
       "      <td>958.344787</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>mnth_10</td>\n",
       "      <td>931.733359</td>\n",
       "      <td>58.155429</td>\n",
       "      <td>300.831829</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>weathersit_1</td>\n",
       "      <td>799.605197</td>\n",
       "      <td>805.001535</td>\n",
       "      <td>491.389395</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>mnth_12</td>\n",
       "      <td>772.941496</td>\n",
       "      <td>-675.761308</td>\n",
       "      <td>-199.455594</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>season_4</td>\n",
       "      <td>738.438403</td>\n",
       "      <td>709.837923</td>\n",
       "      <td>589.169118</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>mnth_11</td>\n",
       "      <td>548.637073</td>\n",
       "      <td>-610.471057</td>\n",
       "      <td>-237.341769</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>weathersit_2</td>\n",
       "      <td>305.260698</td>\n",
       "      <td>283.485003</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>mnth_8</td>\n",
       "      <td>297.994160</td>\n",
       "      <td>36.319840</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>workingday</td>\n",
       "      <td>218.604212</td>\n",
       "      <td>209.455573</td>\n",
       "      <td>29.619139</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>weekday_6</td>\n",
       "      <td>199.112550</td>\n",
       "      <td>182.578689</td>\n",
       "      <td>5.587847</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>weekday_5</td>\n",
       "      <td>124.568266</td>\n",
       "      <td>124.306939</td>\n",
       "      <td>119.027988</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>season_2</td>\n",
       "      <td>110.400044</td>\n",
       "      <td>124.005754</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>season_3</td>\n",
       "      <td>101.446644</td>\n",
       "      <td>106.470624</td>\n",
       "      <td>-0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>mnth_6</td>\n",
       "      <td>68.420351</td>\n",
       "      <td>282.879825</td>\n",
       "      <td>142.391356</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>mnth_5</td>\n",
       "      <td>37.369007</td>\n",
       "      <td>430.570732</td>\n",
       "      <td>285.254004</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>weekday_4</td>\n",
       "      <td>17.272060</td>\n",
       "      <td>29.079490</td>\n",
       "      <td>16.348289</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>weekday_3</td>\n",
       "      <td>-6.322377</td>\n",
       "      <td>3.072918</td>\n",
       "      <td>-0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>instant</td>\n",
       "      <td>-6.971132</td>\n",
       "      <td>1.272780</td>\n",
       "      <td>-0.979553</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>weekday_2</td>\n",
       "      <td>-57.090077</td>\n",
       "      <td>-50.509294</td>\n",
       "      <td>-43.600211</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>weekday_0</td>\n",
       "      <td>-124.586626</td>\n",
       "      <td>-132.906082</td>\n",
       "      <td>-296.556177</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>weekday_1</td>\n",
       "      <td>-152.953796</td>\n",
       "      <td>-155.622660</td>\n",
       "      <td>-145.593965</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31</th>\n",
       "      <td>holiday</td>\n",
       "      <td>-293.130136</td>\n",
       "      <td>-259.128180</td>\n",
       "      <td>-446.739087</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>mnth_7</td>\n",
       "      <td>-376.266654</td>\n",
       "      <td>-368.511624</td>\n",
       "      <td>-474.662905</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>mnth_4</td>\n",
       "      <td>-454.993618</td>\n",
       "      <td>145.732564</td>\n",
       "      <td>-0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>mnth_3</td>\n",
       "      <td>-606.211203</td>\n",
       "      <td>216.712947</td>\n",
       "      <td>36.405604</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>season_1</td>\n",
       "      <td>-950.285090</td>\n",
       "      <td>-940.314301</td>\n",
       "      <td>-1103.645379</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>mnth_2</td>\n",
       "      <td>-1026.132943</td>\n",
       "      <td>7.414244</td>\n",
       "      <td>-161.523299</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>weathersit_3</td>\n",
       "      <td>-1104.865895</td>\n",
       "      <td>-1088.486537</td>\n",
       "      <td>-1387.164198</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>windspeed</td>\n",
       "      <td>-1245.444147</td>\n",
       "      <td>-1096.277524</td>\n",
       "      <td>-1185.336890</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>mnth_1</td>\n",
       "      <td>-1353.665152</td>\n",
       "      <td>-97.936948</td>\n",
       "      <td>-314.313624</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>hum</td>\n",
       "      <td>-1583.508532</td>\n",
       "      <td>-1353.554908</td>\n",
       "      <td>-1524.147901</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         columns      coef_lr   coef_ridge   coef_lasso\n",
       "33            yr  4549.136402  1544.674723  2358.983279\n",
       "27          temp  2707.682487  1765.881620  2679.387928\n",
       "13        mnth_9  1160.174124   574.895356   678.656820\n",
       "28         atemp   934.351609  1527.867002   958.344787\n",
       "14       mnth_10   931.733359    58.155429   300.831829\n",
       "17  weathersit_1   799.605197   805.001535   491.389395\n",
       "16       mnth_12   772.941496  -675.761308  -199.455594\n",
       "4       season_4   738.438403   709.837923   589.169118\n",
       "15       mnth_11   548.637073  -610.471057  -237.341769\n",
       "18  weathersit_2   305.260698   283.485003     0.000000\n",
       "12        mnth_8   297.994160    36.319840     0.000000\n",
       "32    workingday   218.604212   209.455573    29.619139\n",
       "26     weekday_6   199.112550   182.578689     5.587847\n",
       "25     weekday_5   124.568266   124.306939   119.027988\n",
       "2       season_2   110.400044   124.005754     0.000000\n",
       "3       season_3   101.446644   106.470624    -0.000000\n",
       "10        mnth_6    68.420351   282.879825   142.391356\n",
       "9         mnth_5    37.369007   430.570732   285.254004\n",
       "24     weekday_4    17.272060    29.079490    16.348289\n",
       "23     weekday_3    -6.322377     3.072918    -0.000000\n",
       "0        instant    -6.971132     1.272780    -0.979553\n",
       "22     weekday_2   -57.090077   -50.509294   -43.600211\n",
       "20     weekday_0  -124.586626  -132.906082  -296.556177\n",
       "21     weekday_1  -152.953796  -155.622660  -145.593965\n",
       "31       holiday  -293.130136  -259.128180  -446.739087\n",
       "11        mnth_7  -376.266654  -368.511624  -474.662905\n",
       "8         mnth_4  -454.993618   145.732564    -0.000000\n",
       "7         mnth_3  -606.211203   216.712947    36.405604\n",
       "1       season_1  -950.285090  -940.314301 -1103.645379\n",
       "6         mnth_2 -1026.132943     7.414244  -161.523299\n",
       "19  weathersit_3 -1104.865895 -1088.486537 -1387.164198\n",
       "30     windspeed -1245.444147 -1096.277524 -1185.336890\n",
       "5         mnth_1 -1353.665152   -97.936948  -314.313624\n",
       "29           hum -1583.508532 -1353.554908 -1524.147901"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 看看各特征的权重系数，系数的绝对值大小可视为该特征的重要性\n",
    "fs = pd.DataFrame({\"columns\":list(feat_names), \"coef_lr\":list((lr.coef_.T)), \"coef_ridge\":list((ridge.coef_.T)), \"coef_lasso\":list((lasso.coef_.T))})\n",
    "fs.sort_values(by=['coef_lr'],ascending=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lasso模型超参数调优 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "       estimator=Lasso(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=1000,\n",
       "   normalize=False, positive=False, precompute=False, random_state=None,\n",
       "   selection='cyclic', tol=0.0001, warm_start=False),\n",
       "       fit_params=None, iid='warn', n_jobs=None,\n",
       "       param_grid={'alpha': [0.01, 0.1, 1, 10, 100]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring=None, verbose=0)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import Lasso\n",
    "grid_search = GridSearchCV(Lasso(), param_grid, cv=5)\n",
    "grid_search.fit(x_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'alpha': 1}\n"
     ]
    }
   ],
   "source": [
    "print(grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lasso模型评价 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The RMSE of LassoCV on test is 771.9906270743458\n",
      "The RMSE of LassoCV on train is 756.1414520771982\n"
     ]
    }
   ],
   "source": [
    "# 评估，使用RMSE评价模型在测试集和训练集上的性能\n",
    "print('The RMSE of LassoCV on test is', mean_squared_error(y_test, y_test_pred_lasso)**0.5)\n",
    "print('The RMSE of LassoCV on train is', mean_squared_error(y_train, y_train_pred_lasso)**0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The r2_score of LassoCV on test is 0.8375219080216969\n",
      "The r2_score of LassoCV on train is 0.8479974475264037\n"
     ]
    }
   ],
   "source": [
    "# 评估，使用r2_score评价模型在测试集和训练集上的性能\n",
    "print('The r2_score of LassoCV on test is', r2_score(y_test, y_test_pred_lasso))\n",
    "print('The r2_score of LassoCV on train is', r2_score(y_train, y_train_pred_lasso))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 特征系数模型分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### L2正则(岭回归)使得线性回归系数收缩；而L1正则(Lasso)也会收缩回归系数，当正则参数取合适值时，L1正则使得有些回归系数为0，得到稀疏模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
